#!/bin/bash
# Firewalld 安全防护工具
# 功能：
# 1. 自动检测攻击 IP（连接数过多）
# 2. 一键封禁指定 IP（自动识别 zone）
# 3. 查看已封禁 IP
# 4. 解封指定 IP

# 检查 firewalld 是否运行
if ! systemctl is-active --quiet firewalld; then
    echo "❌ firewalld 未运行，请先启动：systemctl start firewalld"
    exit 1
fi

# 获取接口对应 zone
get_zone_for_interface() {
    local iface=$1
    firewall-cmd --get-zone-of-interface="$iface" 2>/dev/null
}

# 自动检测攻击 IP
detect_attack_ips() {
    local threshold=${1:-50}
    echo "🔍 检测连接数超过 $threshold 的 IP..."
    sudo netstat -antp 2>/dev/null | awk '{print $5}' | cut -d: -f1 | \
    grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | sort | uniq -c | sort -nr | \
    awk -v th="$threshold" '$1>th{print $2"\t连接数: "$1}'
}

# 获取所有封禁 IP
list_blocked_ips() {
    echo "📋 已封禁的 IP："
    zones=$(firewall-cmd --get-zones)
    declare -A ip_zone_map
    count=1
    for zone in $zones; do
        rules=$(firewall-cmd --zone="$zone" --list-rich-rules)
        while read -r line; do
            if [[ $line == *"source address="* ]]; then
                ip=$(echo "$line" | grep -oP 'source address="\K[0-9\.]+')
                echo "$count) $ip (zone: $zone)"
                ip_zone_map[$count]="$zone|$ip"
                ((count++))
            fi
        done <<< "$rules"
    done
    [[ $count -eq 1 ]] && echo "✅ 没有发现被封禁的 IP"
}

# 封禁 IP
block_ip() {
    local ip=$1
    if [[ -z $ip ]]; then
        read -p "请输入要封禁的 IP: " ip
    fi
    # 自动识别 zone（取第一个活动 zone）
    local default_zone=$(firewall-cmd --get-active-zones | head -n 1)
    if [[ -z $default_zone ]]; then
        default_zone="public"
    fi
    echo "🚀 封禁 IP: $ip (zone: $default_zone)"
    firewall-cmd --zone="$default_zone" --add-rich-rule="rule family='ipv4' source address='$ip' reject"
    firewall-cmd --permanent --zone="$default_zone" --add-rich-rule="rule family='ipv4' source address='$ip' reject"
    firewall-cmd --reload
    echo "✅ 已封禁 $ip"
}

# 解封 IP
unblock_ip() {
    list_blocked_ips
    read -p "请输入要解封的 IP: " ip
    if [[ -z $ip ]]; then
        echo "⚠️ 请输入有效 IP"
        return
    fi
    zones=$(firewall-cmd --get-zones)
    for zone in $zones; do
        firewall-cmd --zone="$zone" --remove-rich-rule="rule family='ipv4' source address='$ip' reject" >/dev/null 2>&1
        firewall-cmd --zone="$zone" --remove-rich-rule="rule family='ipv4' source address='$ip' drop" >/dev/null 2>&1
        firewall-cmd --permanent --zone="$zone" --remove-rich-rule="rule family='ipv4' source address='$ip' reject" >/dev/null 2>&1
        firewall-cmd --permanent --zone="$zone" --remove-rich-rule="rule family='ipv4' source address='$ip' drop" >/dev/null 2>&1
    done
    firewall-cmd --reload
    echo "✅ 已解封 $ip"
}

# 菜单
while true; do
    echo ""
    echo "========== 🔒 Firewalld 安全防护工具 =========="
    echo "1) 自动检测攻击 IP"
    echo "2) 一键封禁指定 IP"
    echo "3) 查看已封禁 IP"
    echo "4) 解封指定 IP"
    echo "5) 退出"
    read -p "请选择操作 [1-5]: " choice

    case $choice in
        1)
            read -p "请输入连接数阈值(默认50): " threshold
            detect_attack_ips ${threshold:-50}
            ;;
        2)
            read -p "请输入要封禁的 IP: " ip
            block_ip "$ip"
            ;;
        3)
            list_blocked_ips
            ;;
        4)
            unblock_ip
            ;;
        5)
            echo "👋 退出工具"
            exit 0
            ;;
        *)
            echo "⚠️ 无效选项，请重新输入"
            ;;
    esac
done
